<script lang="ts" setup>
import {
  SuccessFilled,
  WarningFilled,
  ArrowLeft,
  ArrowRight,
} from "@element-plus/icons-vue";
import { ref, watch, onActivated, onDeactivated } from "vue";
import { useRoute } from "vue-router";
import { SelectSubjectType } from "./modules/types";
import { SubjectTypeEnum } from "@/enum/question-test/QuestionTestEnum";
import { Swiper, SwiperSlide } from "swiper/vue";
import { Virtual } from "swiper";
import type { Swiper as SwiperType } from "swiper";
import "swiper/css";
import DrawerSubject from "./modules/DrawerSubject.vue";
import { DrawerSubjectExpose } from "./modules/DrawerSubject.vue";
import { storeToRefs } from "pinia";
import { useQuestionStore } from "@/store/modules/question";

const modules = [Virtual];

const route = useRoute();
const questionStore = useQuestionStore();
const {
  total,
  loading,
  curMode,
  subjects,
  curIndex,
  swiperInstance,
  referenceAnswer,
} = storeToRefs(questionStore);

const DrawerSubjectRef = ref<DrawerSubjectExpose>();

// 根据当前模式，初始化数据
watch(
  () => route.query.mode,
  (newVal: unknown) => {
    if (!newVal) return;
    curMode.value = newVal as SubjectTypeEnum;
  },
  { immediate: true }
);

// 页面激活时，初始化试题数据
onActivated(() => {
  // 初始化试题数据
  questionStore.initQuestion();
});

// 刷题路由页面切换时，重置试题数据
onDeactivated(() => {
  // 离开页面时，销毁swiper实例
  swiperInstance.value?.destroy();
  questionStore.rest();
});

// 点击选项
const handleClickOption = (
  item: SelectSubjectType,
  answer: { title: string }
) => {
  questionStore.multipleChoice(item, answer);
};

/**
 * swiper加载完毕时触发
 * @param swiper swiper实例
 */
function onSwiper(swiper: SwiperType) {
  // 加载完毕，结束loading
  loading.value = false;
  // 保存swiper实例
  swiperInstance.value = swiper;
  // 保存当前试题索引
  curIndex.value = swiper.activeIndex;
  // console.log("swiper加载完毕==>", swiperInstance.value);
}

/**
 * swiper滑动时触发
 * @param swiper swiper实例
 */
function handleSlideChange(swiper: SwiperType) {
  // swiper.progress 当前进度 swiper.slides 当前所有的swiper子项dom
  // console.log("swiper滑动时触发==>", swiper);
  curIndex.value = swiper.activeIndex;
}

/**
 * 跳转到指定索引的题目
 * @param index 当前题目索引
 */
function handleSlideTo(index: number) {
  // console.log(`跳转到第：${index} 题`);
  swiperInstance.value?.slideTo(index, 0);
  // 保存当前试题索引
  curIndex.value = index;
  // 跳转完毕，关闭抽屉答题卡
  DrawerSubjectRef.value?.show(false);
}

// 显示答题卡
function handleShowDrawerSubjects() {
  DrawerSubjectRef.value?.show(true);
}

defineOptions({
  name: "Test",
});
</script>

<template>
  <div
    class="test"
    v-loading.fullscreen.lock="loading"
    element-loading-text="🍍加载试题中..."
  >
    <!-- 题型和序号 -->
    <el-row style="margin-bottom: 1rem">
      <el-col :span="24" style="color: #98a0a6; font-size: 1rem"
        ><span style="color: #0077ff; font-weight: bold"
          >🥝【{{ curIndex + 1 }}/{{ total }}】</span
        >{{ curMode }}</el-col
      >
    </el-row>
    <!-- 选择题 -->
    <div class="question" v-if="subjects.length">
      <Swiper
        :grabCursor="true /* 鼠标覆盖Swiper时指针会变成手掌形状 */"
        :modules="modules /* 引入导航、分页、滚动条、无障碍功能 */"
        :autoplay="{
          delay: 2500,
          disableOnInteraction: false,
          reverseDirection: false,
        }"
        :touch-ratio="1"
        :loop="false"
        :space-between="10"
        :virtual="true /* 虚拟swiper，只渲染当前可见的slide和前后的slide */"
        :observer="true /* 修改swiper自己或者子元素时，自动初始化swiper */"
        :observe-parents="true /* 修改swiper的父元素时，自动初始化swiper */"
        @swiper="onSwiper"
        @slide-change="handleSlideChange"
      >
        <SwiperSlide
          v-for="(item, index) in subjects"
          :key="index"
          motion-blur
          class="q-slide-item"
        >
          <!-- 题目 -->
          <el-row style="padding-left: 1px; padding-right: 1px"
            ><el-col :spna="24" class="topic" style="font-weight: bold">{{
              item.topic
            }}</el-col></el-row
          >
          <!-- 选项 -->
          <div
            class="q-option"
            v-for="(option, optionIndex) in item.answers"
            :class="{
              /* 用户选择正确选项样式 */
              'q-selected-correct': subjects[index].target.includes(
                option.title.charAt(0)
              ),
              /* 用户选择错误选项样式 */
              'q-selected-error':
                subjects[index]?.target.includes(option.title.charAt(0)) &&
                !subjects[index]?.correct.includes(option.title.charAt(0)),
            }"
            :key="optionIndex"
            @click="handleClickOption(item, option)"
          >
            <span style="font-weight: 600">{{ option.title }}</span>
          </div>

          <!-- 显示正确答案：触发条件，用户选中错误选项或者用户全对 -->
          <div
            v-show="subjects[index].end"
            class="show-correct-answer"
            style="margin-bottom: 30px; margin-top: 30px"
          >
            <div
              class="f-center"
              v-if="
                subjects[index].correct.every((item) =>
                  subjects[index].target.includes(item)
                )
              "
            >
              <!-- 正确 -->
              <el-icon color="#03C37B" size="18px">
                <SuccessFilled />
              </el-icon>
              <div
                style="font-size: 14px; margin-left: 10px; font-weight: bold"
              >
                恭喜，答对了
              </div>
            </div>

            <!-- 错误 -->
            <div v-else class="f-center">
              <el-icon color="#FF5722" size="18px">
                <WarningFilled />
              </el-icon>

              <div
                style="font-size: 14px; margin-left: 10px; font-weight: bold"
              >
                答错了，再接再厉
              </div>
            </div>

            <!-- 参考答案 -->
            <div style="font-size: 14px; margin-top: 15px">
              <span>参考答案：{{ referenceAnswer }}</span>
              <span
                style="margin-left: 15px"
                :class="{
                  'c-03C37B': subjects[index].correct.every((item) =>
                    subjects[index].target.includes(item)
                  ),
                  'c-FF5722': !subjects[index].correct.every((item) =>
                    subjects[index].target.includes(item)
                  ),
                }"
                >我的答案：{{ subjects[index].target.join("") }}</span
              >
            </div>
          </div>
        </SwiperSlide>
      </Swiper>
    </div>

    <!-- 上一题、下一题按钮 -->
    <div class="btn-control">
      <div
        class="pre"
        type="primary"
        @click="questionStore.handlePrev(swiperInstance)"
      >
        <el-icon class="el-icon--right"><ArrowLeft /></el-icon>上一题
      </div>
      <div class="subjects" @click="handleShowDrawerSubjects">🌺题卡</div>
      <div
        class="next"
        type="primary"
        @click="questionStore.handleNext(swiperInstance)"
      >
        下一题<el-icon class="el-icon--right"><ArrowRight /></el-icon>
      </div>
    </div>

    <DrawerSubject
      v-if="subjects.length"
      :total="total"
      ref="DrawerSubjectRef"
      :subjects="subjects"
      @on-slide-to="handleSlideTo"
    />
  </div>
</template>

<style lang="scss" scoped>
/* vite打包手机本地浏览unocss原子化样式失效问题 */
.f-center {
  display: flex;
  align-items: center;
  justify-content: center;
}
.c-03C37B {
  color: #03c37b;
}
.c-FF5722 {
  color: #ff5722;
}
/* vite打包手机本地浏览unocss原子化样式失效问题 */

.test {
  padding: 20px 10px;
  $t-height: 120px;
  .question {
    .topic {
      width: 100%;
      padding: 10px;
      background: linear-gradient(to right, #ecb53c, #ff9211);
      color: #fff;
      border-radius: 8px 8px 8px 8px;
      margin-bottom: 1rem;
    }

    // 自定义swiper-item容器class样式
    :deep(.q-slide-item) {
      height: calc(100vh - #{$t-height});
    }

    .q-option {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 15px 25px;
      border-radius: 5px;
      font-size: 14px;
      background-color: #f4f8fb;
      &:not(:last-child) {
        margin-bottom: 1rem;
      }
    }

    // 用户选择正确选项
    .q-selected-correct {
      // color: #0077ff;
      color: #289f6b !important;
      background-color: rgb(208 255 240) !important;
    }
    .q-selected-error {
      color: #ff5722 !important;
      background-color: rgb(255 242 242) !important;
    }
  }

  .btn-control {
    position: fixed;
    bottom: 0.5rem;
    left: 0;
    z-index: 10;
    width: 100%;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
    border-top: 2px solid rgba(0, 0, 0, 0.12);
    .pre,
    .subjects,
    .next {
      height: 50px;
      display: flex;
      font-weight: bold;
      align-items: center;
      padding-top: 0.1rem;
    }
    .pre {
      justify-content: start;
      padding-left: 10px;
    }
    .subjects {
      border-top: 3px solid rgba(148, 144, 144, 0.2);
      justify-content: center;
      text-align: center;
    }
    .next {
      justify-content: end;
      padding-right: 10px;
    }
  }
}
</style>
